// File:    defs.h
// Author:  sqbang
// Purpose: report error for ExprEval
//------------------------------------------------------------------------------

#ifndef __EXPREVAL_ERROR_H__
#define __EXPREVAL_ERROR_H__

//C++ headers
#include <sstream>
#include <iostream>
#include <cerrno>
#include <vector>
#include <stdlib.h>

namespace ExprEval
{

enum ErrorCode
{
    GOOD = 0,

    ERROR_DOMAIN,
    ERROR_RANGE,

    INVALID_VALUE
};

class ErrorInfo
{
public:

    ErrorInfo();

    void add_error(const int code, const std::string& location);

    /**
     * if ERROR_CODE != GOOD, error will be reported
     * and abort the program.
     * expr tells when evaluate which expr the error occurs.
     */
    void check_error(const std::string& expr) const;
    
    void setStopWhenNumericLimitsReached (const bool stop);

private:

    /*
     * ERROR_CODE tells which type error
     * ERROR_LOCATION tells where the error
     * pair<ErrorCode, ErrorLocation>
     */
    std::vector<std::pair<ErrorCode, std::string> > m_errors;

    bool m_stop_when_numeric_limits_reached;
};

}

#define SHOW_NONFATAL_ERROR(X)                                                               \
{                                                                                            \
    std::ostringstream tboxos;                                                               \
    tboxos << "Program error in file \"" <<__FILE__<< "\" at line " <<__LINE__<<std::endl; \
    tboxos << "ERROR MESSAGE:" << std::endl;                                                     \
    tboxos <<X<<std::endl;                                                                    \
    std::cout<<tboxos.str() <<std::endl;                                                      \
}

#define SHOW_FATAL_ERROR(X)                                                                  \
{                                                                                            \
    std::ostringstream tboxos;                                                               \
    tboxos << "Program abort called in file \"" <<__FILE__<< "\" at line " <<__LINE__<<std::endl; \
    tboxos << "ERROR MESSAGE:" << std::endl;                                                     \
    tboxos <<X<<std::endl;                                                                    \
    std::cout<<tboxos.str() <<std::endl;                                                      \
    exit (0);                                                                                 \
}

#endif
